﻿using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections.Generic;

namespace Rcon
{
    public partial class RconForm : Form
    {
		private delegate void VoidDel();
		private delegate void StringDel(string s);
		private delegate void ColorDel(Color c);
		private delegate void TBoxDel(TextBox tb, Color c);

        private string cellContents = string.Empty;
        private List<Match> matches = new List<Match>();
        private List<Message> messages = new List<Message>();

		private RConV1 rcon = new RConV1();

		/// <summary>
		/// Commands for consideration:
		/// playlist_enabled					-> should be true (1)
		/// playlist							-> string of numbers that associate to a gametype
		///	playlist_excludeGametypeMap "ARG"	-> args of form mp_$MAP_NAME or mp_$GAME_TYPE mp_$MAP_NAME
		/// 
		/// </summary>
        public RconForm()
        {
            InitializeComponent();
            PopulateFields();
        }

        #region Misc - Not interesting
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ProcessStartInfo browser = new ProcessStartInfo(e.Link.LinkData.ToString());
            Process.Start(browser);
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            ProcessStartInfo browser = new ProcessStartInfo("http://www.gameservers.com/clanpay/?clanid=1bd3a3dc454ab2b0dea4851d254632bc");
            Process.Start(browser);
        }

        private void optionTabs_Selecting(object sender, TabControlCancelEventArgs e)
        {
            /*if (!rcon.Connected && e.TabPageIndex > 0)
                e.Cancel = true;*/
        }

        private void mapCheckTimer_Tick(object sender, EventArgs e)
        {
            // Timer to call mapQuery in RconV# class, all work done in there
            rcon.mapQuery();
        }

        private void queryServer_Tick(object sender, EventArgs e)
        {
            // Timer to call playListQuery in RconV# class, all work done in there
            rcon.playListQuery();
        }

        private void messageDisplayTimer_Tick(object sender, EventArgs e)
        {
            this.messageDisplayTimer.Enabled = false;
            this.messageDisplayTimer.Stop();
            int seconds = rcon.displayMessage();
            this.messageDisplayTimer.Interval = seconds * 1000;
            this.messageDisplayTimer.Enabled = true;
            this.messageDisplayTimer.Start();
        }

        private void RconForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            WriteSettings();
        }
        #endregion

        #region Properties.Settings
        private void PopulateFields()                                   // Message Class needs to be updated here
        {
            this.textBoxIP.Text = Rcon.Properties.Settings.Default.textBoxIP;
            this.textBoxPort.Text = Rcon.Properties.Settings.Default.textBoxPort;
            this.textBoxPWord.Text = Rcon.Properties.Settings.Default.textBoxPWord;
            StringCollection mapGametypeList = new StringCollection();
            mapGametypeList = Rcon.Properties.Settings.Default.listBoxMatches;
            this.listBoxMatches.Items.Clear();
            string[] args;
            if (mapGametypeList != null)
            {
                Match newMatch = new Match();
                foreach (string gmp in mapGametypeList)
                    this.listBoxMatches.Items.Add(newMatch.FromUglyString(gmp));
            }
            mapGametypeList = Rcon.Properties.Settings.Default.listBoxMessages;
            this.listBoxMessages.Rows.Clear();
            int dur;
            if (mapGametypeList != null)
            {
                Message message;
                DataGridViewRow dgvr;
                foreach (string row in mapGametypeList)
                {
                    args = Regex.Split(row, ";");
                    if(args.Length.Equals(4))
                    {
                        if (!string.IsNullOrEmpty(args[0]) && int.TryParse(args[1], out dur) && dur > 0 && !string.IsNullOrEmpty(args[2]) && !string.IsNullOrEmpty(args[3]))
                        {
                            message = new Message(args[0], dur, args[2], args[3]);
                            dgvr = new DataGridViewRow();
                            dgvr.CreateCells(this.listBoxMessages);
                            this.listBoxMessages.Rows.Add(message.ToRow(dgvr));
                        }
                    }
                }
            }
        }

        private void WriteSettings()            // Figure something out with the Message Class in here
        {
            Rcon.Properties.Settings.Default.textBoxIP = this.textBoxIP.Text;
            Rcon.Properties.Settings.Default.textBoxPort = this.textBoxPort.Text;
            Rcon.Properties.Settings.Default.textBoxPWord = this.textBoxPWord.Text;
            StringCollection lbsc = new StringCollection();
            foreach (Match match in this.listBoxMatches.Items)
                lbsc.Add(match.ToUglyString());
            Rcon.Properties.Settings.Default.listBoxMatches = lbsc;
            List<string> lbsa = new List<string>(this.listBoxMessages.Rows.Count);
            Message message = new Message();
            foreach (DataGridViewRow row in this.listBoxMessages.Rows)
            {
                lbsa.Add(message.FromRow(row).ToString());
            }
            lbsc = new StringCollection();
            foreach (string entry in lbsa)
                lbsc.Add(entry);
            Rcon.Properties.Settings.Default.listBoxMessages = lbsc;
            Rcon.Properties.Settings.Default.Save();
        }

        #endregion

        #region Status
        private void SetStatus(string text)
		{
			if (this.InvokeRequired)
			{
				StringDel d = new StringDel(this.SetStatus);
				this.Invoke(d, new object[] { text });
			}
			else
			{
				toolStripStatusLabel.Text = text;
			}
		}

		private void SetStatusColor(Color color)
		{
			if (this.InvokeRequired)
			{
				ColorDel d = new ColorDel(this.SetStatusColor);
				this.Invoke(d, new object[] { color });
			}
			else
			{
				toolStripStatusLabel.BackColor = color;
			}
		}

        private void SetStatusTextColor(Color color)
        {
            if (this.InvokeRequired)
            {
                ColorDel d = new ColorDel(this.SetStatusTextColor);
                this.Invoke(d, new object[] { color });
            }
            else
            {
                toolStripStatusLabel.ForeColor = color;
            }
        }

		private void ClearStatus()
		{
			if (this.InvokeRequired)
			{
				VoidDel d = new VoidDel(this.ClearStatus);
				this.Invoke(d);
			}
			else
			{
				this.SetStatus("");
			}
		}

		private void SetTextBoxColor(TextBox tb, Color c)
		{
			if (this.InvokeRequired)
			{
				TBoxDel d = new TBoxDel(this.SetTextBoxColor);
				this.Invoke(d, new object[] { tb, c });
			}
			else
			{
				tb.BackColor = c;
			}
		}
        #endregion

        #region Form Loading
        private void RconForm_Load(object sender, EventArgs e)                  // Get picture and link working for donation
		{
			this.MaximumSize = this.Size;
			this.MinimumSize = this.Size;
			this.MaximizeBox = false;

            // Can't disconnect on launch, we aren't connected to anything!
            this.buttonDisconnect.Enabled = false;

			this.linkLabel.Links.Remove(linkLabel.Links[0]);
			this.linkLabel.Links.Add(0, linkLabel.Text.Length, "http://www.luckyatbingo.net");

            // Load in Map and Gametype Lists to populate listboxes
            GametypeLookup game = new GametypeLookup();
            MapLookup map = new MapLookup();
            this.listBoxMaps.Items.Clear();
            this.listBoxMaps.Items.AddRange(map.GetPrettyNames());
            this.listBoxGameTypes.Items.Clear();
            this.listBoxGameTypes.Items.AddRange(game.GetPlayListNames());
            this.comboBoxGametypeSelect.Items.Clear();
            this.comboBoxGametypeSelect.Items.AddRange(game.GetUniquePlayListNames());
            this.comboBoxGametypeSelect.SelectedIndex = 0;
            this.comboBoxMapSelect.Items.Clear();
            this.comboBoxMapSelect.Items.Add("Any");
            this.comboBoxMapSelect.Items.AddRange(map.GetPrettyNames());
            this.comboBoxMapSelect.SelectedIndex = 0;
            this.listBoxMatches.AllowDrop = true;
            this.listBoxMessages.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;     // Set Duration column alignment to center
            this.checkListBoxMatchesSize();
            this.checkListBoxMessagesSize();
		}
        #endregion

        #region Connections

        private void textBoxIP_TextChanged(object sender, EventArgs e)
		{
			try
			{
				string text = textBoxIP.Text;
				System.Net.IPAddress.Parse(text);

				this.SetTextBoxColor(sender as TextBox, Color.LightGreen);
				this.ClearStatus();
                if (string.IsNullOrEmpty(this.textBoxIP.Text) == false && string.IsNullOrEmpty(this.textBoxPort.Text) == false && string.IsNullOrEmpty(this.textBoxPWord.Text) == false)
                    this.buttonConnect.Enabled = true;
                else
                    this.buttonConnect.Enabled = false;
			}
			catch (Exception ex)
			{
				this.SetStatus(ex.Message);
                this.SetStatusTextColor(Color.Red);
                this.buttonConnect.Enabled = false;
			}
		}

		private void textBoxPort_TextChanged(object sender, EventArgs e)
		{
			try
			{
				string text = textBoxPort.Text;
				int port = int.Parse(text);
				if (port < 1 || 65535 < port) {
					throw new Exception(port + " is not a valid port number");
				}

				this.SetTextBoxColor(sender as TextBox, Color.LightGreen);
				this.ClearStatus();
                if (string.IsNullOrEmpty(this.textBoxIP.Text) == false && string.IsNullOrEmpty(this.textBoxPort.Text) == false && string.IsNullOrEmpty(this.textBoxPWord.Text) == false)
                    this.buttonConnect.Enabled = true;
                else
                    this.buttonConnect.Enabled = false;
			}
			catch (Exception ex)
			{
				this.SetStatus(ex.Message);
                this.SetStatusTextColor(Color.Red);
                this.buttonConnect.Enabled = false;
			}
		}

		private void textBoxPWord_TextChanged(object sender, EventArgs e)
		{
			try
			{
				// not gonna validate that
                if (string.IsNullOrEmpty(this.textBoxIP.Text) == false && string.IsNullOrEmpty(this.textBoxPort.Text) == false && string.IsNullOrEmpty(this.textBoxPWord.Text) == false)
                    this.buttonConnect.Enabled = true;
                else
                    this.buttonConnect.Enabled = false;
			}
			catch (Exception ex)
			{
				this.SetStatus(ex.Message);
                this.SetStatusTextColor(Color.Red);
                this.buttonConnect.Enabled = false;
			}
		}

		private void buttonConnect_Click(object sender, EventArgs e)
		{
			try
			{
				string remoteHost = textBoxIP.Text;
				int port = int.Parse(textBoxPort.Text);
				string password = textBoxPWord.Text;

				bool connected = rcon.Connect(remoteHost, port, password);
				if (connected)
				{
					this.SetStatus("Connected");
                    this.SetStatusTextColor(Color.Green);
                    this.buttonConnect.Enabled = false;
                    this.textBoxIP.Enabled = false;
                    this.textBoxPort.Enabled = false;
                    this.textBoxPWord.Enabled = false;
                    this.buttonDisconnect.Enabled = true;
                    this.queryServer.Enabled = true;
                    WriteSettings();
				}
				else
				{
					this.SetStatus("Connection failed");
                    this.SetStatusTextColor(Color.Red);
				}
			}
			catch (Exception ex)
			{
				this.SetStatus(ex.Message);
                this.SetStatusTextColor(Color.Red);
			}
		}

        private void buttonDisconnect_Click(object sender, EventArgs e)
        {
            this.textBoxIP.Enabled = true;
            this.textBoxPort.Enabled = true;
            this.textBoxPWord.Enabled = true;
            this.buttonDisconnect.Enabled = false;
            this.SetStatus("Disonnected from " + this.textBoxIP.Text);
            this.SetStatusTextColor(Color.Green);
            this.queryServer.Enabled = false;
            WriteSettings();
            rcon.Reset();
            this.buttonConnect.Enabled = true;
        }

		#endregion

        #region Map Rotation Buttons
        private void buttonLoadRotation_Click(object sender, EventArgs e)
        {
            if (this.listBoxMatches.Items.Count > 0)
            {
                if (MessageBox.Show("Loading a config file will overwrite the current rotation, continue?", "Confirm Load", MessageBoxButtons.YesNo) == DialogResult.No)
                    return;
            }
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Select the Rotation List File";
            fdlg.InitialDirectory = Directory.GetCurrentDirectory();
            fdlg.Filter = "CFG files (*.cfg*)|*.cfg*|All files (*.*)|*.*";
            fdlg.FilterIndex = 1;
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                this.listBoxMatches.Items.Clear();
                // Load in contents of file
                List<Match> matches = rcon.loadMapRotationConfig(fdlg.FileName);
                foreach (Match match in matches)
                {
                    this.listBoxMatches.Items.Add(match);
                }
                this.SetStatus(DateTime.Now.ToLongTimeString() + ": Configuration Successfully Loaded from File");
                this.SetStatusTextColor(Color.Green);
            }
            else
            {
                this.SetStatus(DateTime.Now.ToLongTimeString() + ": Configuration Load Failed");
                this.SetStatusTextColor(Color.Red);
            }
            fdlg.Dispose();
            fdlg = null;
            this.buttonUpdateRotation.Enabled = true;
            this.buttonSaveRotation.Enabled = true;
        }

        private void buttonSaveRotation_Click(object sender, EventArgs e)
        {
            SaveFileDialog fdlg = new SaveFileDialog();
            fdlg.InitialDirectory = Directory.GetCurrentDirectory();
            fdlg.RestoreDirectory = true;
            fdlg.Title = "Select a Location to Save Rotation File";
            fdlg.DefaultExt = "cfg";
            fdlg.Filter = "Config files (*.cfg)|*.cfg|All files (*.*)|*.*";
            fdlg.FilterIndex = 1;
            fdlg.CheckFileExists = false;
            fdlg.CheckPathExists = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                bool success = false;
                bool fileValid = false;
                try
                {
                    new FileInfo(fdlg.FileName);
                    fileValid = true;
                }
                catch { }
                if(fileValid)
                {
                    // Save contents of listbox to file
                    List<Match> entries = new List<Match>();
                    Match match;
                    foreach (object item in this.listBoxMatches.Items)
                    {
                        if (item is Match)
                        {
                            match = item as Match;
                            entries.Add(match);
                        }
                    }
                    success = rcon.saveMapRotationConfig(entries, fdlg.FileName);
                }
                if (success)
                {
                    FileInfo fInfo = new FileInfo(fdlg.FileName);
                    fInfo.IsReadOnly = true;
                    this.SetStatus(DateTime.Now.ToLongTimeString() + ": File Successfully Written to File");
                    this.SetStatusTextColor(Color.Green);
                }
                else
                {
                    this.SetStatus(DateTime.Now.ToLongTimeString() + ": Write to File Failed");
                    this.SetStatusTextColor(Color.Red);
                }
            }
            fdlg.Dispose();
            fdlg = null;
        }

        private void buttonUpdateRotation_Click(object sender, EventArgs e)
        {
            this.buttonUpdateRotation.Enabled = false;
            this.mapCheckTimer.Enabled = false;
            this.mapCheckTimer.Stop();
            List<Match> matches = new List<Match>();
            Match match;
            foreach (object item in this.listBoxMatches.Items)
            {
                if (item is Match)
                {
                    match = item as Match;
                    matches.Add(match);
                }
            }
            rcon.setGametypeMapLists(matches);
            this.mapCheckTimer.Enabled = true;
            this.mapCheckTimer.Start();
        }
        #endregion

        #region Match ListBox Buttons
        private void buttonMoveItemDown_Click(object sender, EventArgs e)
        {
            int index = this.listBoxMatches.SelectedIndex;
            if (this.listBoxMatches.Items[index] is Match)
            {
                Match match = this.listBoxMatches.Items[index] as Match;
                this.listBoxMatches.Items.RemoveAt(index);
                this.listBoxMatches.Items.Insert(index + 1, match);
                this.listBoxMatches.SelectedIndex = index + 1;
                this.listBoxMatches_SelectedIndexChanged(sender, e);
                //this.checkListBoxMatchesSize();
            }
        }

        private void buttonMoveItemUp_Click(object sender, EventArgs e)
        {
            int index = this.listBoxMatches.SelectedIndex;
            if (this.listBoxMatches.Items[index] is Match)
            {
                Match match = this.listBoxMatches.Items[index] as Match;
                this.listBoxMatches.Items.RemoveAt(index);
                this.listBoxMatches.Items.Insert(index - 1, match);
                this.listBoxMatches.SelectedIndex = index - 1;
                this.listBoxMatches_SelectedIndexChanged(sender, e);
                //this.checkListBoxMatchesSize();
            }
        }

        private void buttonAddToList_Click(object sender, EventArgs e)
        {
            string map = this.listBoxMaps.Text;
            string game = this.listBoxGameTypes.Text;
            Match newMatch = new Match(new Map(new MapLookup().GetUglyName(map), map), new GameType(new GametypeLookup().GetPlayListNumber(game), game));
            this.listBoxMatches.Items.Add(newMatch);
            this.buttonAddToList.Enabled = false;
            this.checkListBoxMatchesSize();
        }

        private void buttonRemoveFromList_Click(object sender, EventArgs e)
        {
            this.listBoxMatches.Items.RemoveAt(this.listBoxMatches.SelectedIndex);
            this.buttonRemoveFromList.Enabled = false;
            this.buttonMoveItemUp.Enabled = false;
            this.buttonMoveItemDown.Enabled = false;
            this.checkListBoxMatchesSize();
        }
        #endregion

        #region Map ListBox Changes
        private void listBoxGameTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            // For enabling Add To List Button
            if (this.listBoxMaps.SelectedIndex != -1 && this.listBoxGameTypes.SelectedIndex != -1)
                this.buttonAddToList.Enabled = true;
            else
                this.buttonAddToList.Enabled = false;
        }

        private void listBoxMaps_SelectedIndexChanged(object sender, EventArgs e)
        {
            // For enabling Add To List Button
            if (this.listBoxMaps.SelectedIndex != -1 && this.listBoxGameTypes.SelectedIndex != -1)
                this.buttonAddToList.Enabled = true;
            else
                this.buttonAddToList.Enabled = false;
            
        }

        private void listBoxMatches_SelectedIndexChanged(object sender, EventArgs e)
        {
            // For enabling Remove From List Button
            if (this.listBoxMatches.SelectedIndex != -1)
                this.buttonRemoveFromList.Enabled = true;
            else
                this.buttonRemoveFromList.Enabled = false;
            if (this.listBoxMatches.Items.Count == 1)
            {
                this.buttonMoveItemUp.Enabled = false;
                this.buttonMoveItemDown.Enabled = false;
            }
            else
            {
                if (this.listBoxMatches.SelectedIndex > 0)
                    this.buttonMoveItemUp.Enabled = true;
                else
                    this.buttonMoveItemUp.Enabled = false;
                if (this.listBoxMatches.SelectedIndex < this.listBoxMatches.Items.Count - 1)
                    this.buttonMoveItemDown.Enabled = true;
                else
                    this.buttonMoveItemDown.Enabled = false;
            }
        }
        #endregion

        #region Check Sizes of Listboxes and Datagridviews
        private void checkListBoxMatchesSize()
        {
            if (this.listBoxMatches.Items.Count == 0)
            {
                this.buttonUpdateRotation.Enabled = false;
                this.buttonSaveRotation.Enabled = false;
                this.contextMenuRemoveMatch.Enabled = false;
            }
            else
            {
                this.buttonUpdateRotation.Enabled = true;
                this.buttonSaveRotation.Enabled = true;
                this.contextMenuRemoveMatch.Enabled = true;
            }
            this.WriteSettings();
        }

        private void checkListBoxMessagesSize()
        {
            if (this.listBoxMessages.Rows.Count == 0)
            {
                this.buttonUpdateMessageRotation.Enabled = false;
                this.buttonSaveMessageRotation.Enabled = false;
                this.buttonUpdateMessage.Enabled = false;
            }
            else
            {
                this.buttonUpdateMessageRotation.Enabled = true;
                this.buttonSaveMessageRotation.Enabled = true;
            }
            this.WriteSettings();
        }
        #endregion
        
        #region Color Buttons
        private void buttonBlackText_Click(object sender, EventArgs e)      { insertColorCode("^0"); }
        private void buttonRedText_Click(object sender, EventArgs e)        { insertColorCode("^1"); }
        private void buttonGreenText_Click(object sender, EventArgs e)      { insertColorCode("^2"); }
        private void buttonYellowText_Click(object sender, EventArgs e)     { insertColorCode("^3"); }
        private void buttonBlueText_Click(object sender, EventArgs e)       { insertColorCode("^4"); }
        private void buttonCyanText_Click(object sender, EventArgs e)       { insertColorCode("^5"); }
        private void buttonMagentaText_Click(object sender, EventArgs e)    { insertColorCode("^6"); }
        private void buttonWhiteText_Click(object sender, EventArgs e)      { insertColorCode("^7"); }
        private void buttonGreyText_Click(object sender, EventArgs e)       { insertColorCode("^8"); }
        private void buttonBrownText_Click(object sender, EventArgs e)      { insertColorCode("^9"); }
        private void insertColorCode(string code)
        {
            int pos = this.textboxMessage.SelectionStart;
            this.textboxMessage.Text = this.textboxMessage.Text.Insert(pos, code);
            this.textboxMessage.SelectionStart = pos + 2;
            this.textboxMessage.Focus();
        }
        #endregion

        #region Message Add/Remove/Up/Down/Update
        private void buttonAddMessage_Click(object sender, EventArgs e)
        {
            int duration;
            if (!String.IsNullOrEmpty(this.textboxMessage.Text) && int.TryParse(this.textBoxMessageDuration.Text, out duration) == true && duration > 0 && !String.IsNullOrEmpty(this.textBoxMessageDuration.Text))
            {
                DataGridViewRow row = new DataGridViewRow();
                row.CreateCells(this.listBoxMessages);
                Message mess = new Message(this.textboxMessage.Text, Convert.ToInt16(this.textBoxMessageDuration.Text), this.comboBoxGametypeSelect.SelectedItem.ToString(), this.comboBoxMapSelect.SelectedItem.ToString());
                this.listBoxMessages.Rows.Add(mess.ToRow(row));
            }
            this.checkListBoxMessagesSize();
        }

        private void buttonRemoveMessage_Click(object sender, EventArgs e)
        {
            if(this.listBoxMessages.SelectedRows.Count != 0)
                this.listBoxMessages.Rows.RemoveAt(this.listBoxMessages.SelectedRows[0].Index);
            this.checkListBoxMessagesSize();
        }

        private void buttonMessageMoveUp_Click(object sender, EventArgs e)
        {
            if (this.listBoxMessages.SelectedRows.Count != 0)
            {
                DataGridViewRow row = this.listBoxMessages.SelectedRows[0];
                int rowNum = row.Index;
                if (rowNum > 0)
                {
                    this.listBoxMessages.Rows.RemoveAt(rowNum);
                    this.listBoxMessages.Rows.Insert(rowNum - 1, row);
                    this.listBoxMessages.Rows[rowNum].Selected = false;
                    this.listBoxMessages.Rows[rowNum - 1].Selected = true;
                }
            }
            //this.checkListBoxMessagesSize();
        }

        private void buttonMessageMoveDown_Click(object sender, EventArgs e)
        {
            if (this.listBoxMessages.SelectedRows.Count != 0)
            {
                DataGridViewRow row = this.listBoxMessages.SelectedRows[0];
                int rowNum = row.Index;
                if (rowNum < this.listBoxMessages.Rows.Count - 1)
                {
                    this.listBoxMessages.Rows.RemoveAt(rowNum);
                    this.listBoxMessages.Rows.Insert(rowNum + 1, row);
                    this.listBoxMessages.Rows[rowNum].Selected = false;
                    this.listBoxMessages.Rows[rowNum + 1].Selected = true;
                }
            }
            //this.checkListBoxMessagesSize();
        }
        
        private void buttonUpdateMessage_Click(object sender, EventArgs e)
        {
            int selectedRows = this.listBoxMessages.Rows.GetRowCount(DataGridViewElementStates.Selected);
            int duration;
            if (selectedRows != 0)
            {
                if (string.IsNullOrEmpty(this.textboxMessage.Text) == false && int.TryParse(this.textBoxMessageDuration.Text, out duration) == true && duration > 0 && this.comboBoxGametypeSelect.SelectedIndex != -1)
                {
                    DataGridViewRow row = this.listBoxMessages.SelectedRows[0];
                    row.Cells[0].Value = this.textboxMessage.Text;
                    row.Cells[1].Value = duration;
                    row.Cells[2].Value = this.comboBoxGametypeSelect.SelectedItem;
                    row.Cells[3].Value = this.comboBoxMapSelect.SelectedItem;
                }
            }
        }
        #endregion

        #region Message Rotation
        private void buttonUpdateMessageRotation_Click(object sender, EventArgs e)
        {
            this.buttonUpdateMessageRotation.Enabled = false;
            this.messageDisplayTimer.Enabled = false;
            this.messageDisplayTimer.Stop();
            List<Message> messages = new List<Message>();
            Message mess = new Message();
            foreach (DataGridViewRow row in this.listBoxMessages.Rows)
                messages.Add(mess.FromRow(row));
            if (messages.Count > 0)
            {
                rcon.setMessageLists(messages);
                this.messageDisplayTimer.Enabled = true;
                this.messageDisplayTimer.Start();
            }
        }

        private void buttonSaveMessageRotation_Click(object sender, EventArgs e)
        {
            SaveFileDialog fdlg = new SaveFileDialog();
            fdlg.InitialDirectory = Directory.GetCurrentDirectory();
            fdlg.RestoreDirectory = true;
            fdlg.Title = "Select a Location to Save Rotation File";
            fdlg.DefaultExt = "cfg";
            fdlg.Filter = "Config files (*.cfg)|*.cfg|All files (*.*)|*.*";
            fdlg.FilterIndex = 1;
            fdlg.CheckFileExists = false;
            fdlg.CheckPathExists = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                bool success = false;
                bool fileValid = false;
                try
                {
                    new FileInfo(fdlg.FileName);
                    fileValid = true;
                }
                catch { }
                if (fileValid)
                {
                    // Save contents of listbox to file
                    List<Message> args = new List<Message>(this.listBoxMessages.Rows.Count);
                    string arg = string.Empty;
                    int duration = -1;
                    Message message = new Message();
                    foreach (DataGridViewRow entry in this.listBoxMessages.Rows)
                    {
                        if (!string.IsNullOrEmpty(entry.Cells[0].Value.ToString()) && int.TryParse(entry.Cells[1].Value.ToString(), out duration) == true && duration > 0 && entry.Cells[2].Value != null && entry.Cells[3].Value != null)
                        {
                            args.Add(message.FromRow(entry));
                        }
                    }
                    success = rcon.saveMessageRotationConfig(args, fdlg.FileName);
                }
                if (success)
                {
                    FileInfo fInfo = new FileInfo(fdlg.FileName);
                    fInfo.IsReadOnly = true;
                    this.SetStatus(DateTime.Now.ToLongTimeString() + ": File Successfully Written to File");
                    this.SetStatusTextColor(Color.Green);
                }
                else
                {
                    this.SetStatus(DateTime.Now.ToLongTimeString() + ": Write to File Failed");
                    this.SetStatusTextColor(Color.Red);
                }
            }
            fdlg.Dispose();
            fdlg = null;
        }

        private void buttonLoadMessageRotation_Click(object sender, EventArgs e)
        {
            if (this.listBoxMessages.Rows.Count > 0)
            {
                if (MessageBox.Show("Loading a config file will overwrite the current rotation, continue?", "Confirm Load", MessageBoxButtons.YesNo) == DialogResult.No)
                    return;
            }
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Select the Rotation List File";
            fdlg.InitialDirectory = Directory.GetCurrentDirectory();
            fdlg.Filter = "CFG files (*.cfg*)|*.cfg*|All files (*.*)|*.*";
            fdlg.FilterIndex = 1;
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                this.listBoxMessages.Rows.Clear();
                // Load in contents of file
                List<Message> options = rcon.loadMessageRotationConfig(fdlg.FileName);
                int rowNum = -1;
                foreach (Message entry in options)
                {
                    if (!string.IsNullOrEmpty(entry.GetMessage) && entry.GetDuration > 0 && !string.IsNullOrEmpty(entry.GetGametype) && !string.IsNullOrEmpty(entry.GetMap))
                    {
                        rowNum = this.listBoxMessages.Rows.Add();
                        this.listBoxMessages.Rows[rowNum].Cells[0].Value = entry.GetMessage;
                        this.listBoxMessages.Rows[rowNum].Cells[1].Value = entry.GetDuration;
                        this.listBoxMessages.Rows[rowNum].Cells[2].Value = entry.GetGametype;
                        this.listBoxMessages.Rows[rowNum].Cells[3].Value = entry.GetMap;
                    }
                }
                this.SetStatus(DateTime.Now.ToLongTimeString() + ": Configuration Successfully Loaded from File");
                this.SetStatusTextColor(Color.Green);
            }
            else
            {
                this.SetStatus(DateTime.Now.ToLongTimeString() + ": Configuration Load Failed");
                this.SetStatusTextColor(Color.Red);
            }
            fdlg.Dispose();
            fdlg = null;
            this.buttonUpdateRotation.Enabled = true;
            this.buttonSaveRotation.Enabled = true;
            this.checkListBoxMessagesSize();
        }
        #endregion

        #region Message Field Changes
        private void textboxMessage_TextChanged(object sender, EventArgs e)
        {
            if (this.textboxMessage.Text.Length.Equals(0) || this.textBoxMessageDuration.Text.Length.Equals(0))
                this.buttonAddMessage.Enabled = false;
            else
            {
                try
                {
                    int dur = Convert.ToInt16(this.textBoxMessageDuration.Text);
                    if (dur > 0)
                        this.buttonAddMessage.Enabled = true;
                }
                catch
                {
                    this.buttonAddMessage.Enabled = false;
                }
            }
        }

        private void textBoxMessageDuration_TextChanged(object sender, EventArgs e)
        {
            if (this.textboxMessage.Text.Length.Equals(0) || this.textBoxMessageDuration.Text.Length.Equals(0))
                this.buttonAddMessage.Enabled = false;
            else
            {
                try
                {
                    int dur = Convert.ToInt16(this.textBoxMessageDuration.Text);
                    if (dur > 0)
                        this.buttonAddMessage.Enabled = true;
                }
                catch
                {
                    this.buttonAddMessage.Enabled = false;
                }
            }
        }

        private void comboBoxGametypeSelect_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void comboBoxMapSelect_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        #endregion

        #region Message DataGrid View Changes
        private void listBoxMessages_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listBoxMessages_SelectionChanged(object sender, EventArgs e)
        {
            // For enabling Remove From List Button
            int rowsSelected = this.listBoxMessages.Rows.GetRowCount(DataGridViewElementStates.Selected);
            if (rowsSelected != 0)
            {
                this.buttonRemoveMessage.Enabled = true;
                this.buttonUpdateMessage.Enabled = true;
                DataGridViewRow row = this.listBoxMessages.SelectedRows[0];
                if (row.Cells[0].Value != null && row.Cells[1].Value != null && row.Cells[2].Value != null && row.Cells[3].Value != null)
                {
                    this.textboxMessage.Text = row.Cells[0].Value.ToString();
                    this.textBoxMessageDuration.Text = row.Cells[1].Value.ToString();
                    this.comboBoxGametypeSelect.SelectedIndex = this.comboBoxGametypeSelect.FindStringExact(row.Cells[2].Value.ToString());
                    this.comboBoxMapSelect.SelectedIndex = this.comboBoxMapSelect.FindStringExact(row.Cells[3].Value.ToString());
                }
                this.listBoxMessages.Rows[this.listBoxMessages.SelectedRows[0].Index].Selected = true;
                if (this.listBoxMessages.SelectedRows[0].Index > 0)
                    this.buttonMessageMoveUp.Enabled = true;
                else
                    this.buttonMessageMoveUp.Enabled = false;
                if (this.listBoxMessages.SelectedRows[0].Index < this.listBoxMessages.Rows.Count - 1)
                    this.buttonMessageMoveDown.Enabled = true;
                else
                    this.buttonMessageMoveDown.Enabled = false;
            }
            else
            {
                this.buttonRemoveMessage.Enabled = false;
                this.buttonMessageMoveUp.Enabled = false;
                this.buttonMessageMoveDown.Enabled = false;
                this.buttonUpdateMessage.Enabled = false;
            }
            if (this.listBoxMessages.Rows.Count == 1)
            {
                this.buttonMessageMoveUp.Enabled = false;
                this.buttonMessageMoveDown.Enabled = false;
            }
        }

        private void listBoxMessages_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if(this.listBoxMessages.CurrentCell.Value != null)
                this.cellContents = this.listBoxMessages.CurrentCell.Value.ToString();
        }

        private void listBoxMessages_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (this.listBoxMessages.CurrentCell.ColumnIndex.Equals(0))
            {
                if (this.listBoxMessages.CurrentCell.Value == null)
                {
                    MessageBox.Show("Must have a string entered here", "Input Error");
                    this.listBoxMessages.CurrentCell.Value = this.cellContents.ToString();
                }
            }
            else if (this.listBoxMessages.CurrentCell.ColumnIndex.Equals(1))
            {
                try
                {
                    int val = Convert.ToInt16(this.listBoxMessages.CurrentCell.Value);
                    if (val <= 0)
                    {
                        MessageBox.Show("Value must be an integer greater than 0", "Input Error");
                        this.listBoxMessages.CurrentCell.Value = this.cellContents.ToString();
                    }
                }
                catch
                {
                    MessageBox.Show("Value must be an integer greater than 0", "Input Error");
                    this.listBoxMessages.CurrentCell.Value = this.cellContents.ToString();
                }
            }
        }

        private void listBoxMessages_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
        #endregion

        #region Match List Box Drag-and-Drop
        private void listBoxMatches_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button.Equals(MouseButtons.Left))
            {
                if (this.listBoxMatches.SelectedIndex != -1)
                    this.listBoxMatches.DoDragDrop(this.listBoxMatches.SelectedItem, DragDropEffects.Move);
            }
            else if (e.Button.Equals(MouseButtons.Right))
            {
                Point point = new Point(e.X, e.Y);
                int index = this.listBoxMatches.IndexFromPoint(point);
                this.listBoxMatches.SelectedIndex = index;
                if (!index.Equals(-1))
                    this.contextMenuRemoveMatch.Enabled = true;
                else
                    this.contextMenuRemoveMatch.Enabled = false;
            }
        }

        private void listBoxMatches_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }

        private void listBoxMatches_DragDrop(object sender, DragEventArgs e)
        {
            Point point = this.listBoxMatches.PointToClient(new Point(e.X, e.Y));
            int index = this.listBoxMatches.IndexFromPoint(point);
            object data = e.Data.GetData(typeof(Match));
            this.listBoxMatches.Items.Remove(data);
            if (index != -1)
                this.listBoxMatches.Items.Insert(index, data);
            else
                this.listBoxMatches.Items.Add(data);
            this.listBoxMatches.SelectedIndex = index;
            this.listBoxMatches_SelectedIndexChanged(sender, new EventArgs());
        }
        #endregion

        private void removeMatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(!this.listBoxMatches.SelectedIndex.Equals(-1))
                this.listBoxMatches.Items.RemoveAt(this.listBoxMatches.SelectedIndex);
        }

        private void contextMenuRemoveMatch_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = this.listBoxMatches.SelectedIndex.Equals(-1);
            contextMenuRemoveMatch.Enabled = this.listBoxMatches.Items.Count > 0;
        }

        private void contextMenuHideGametype_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = this.listBoxGameTypes.SelectedIndex.Equals(-1);
            contextMenuHideGametype.Enabled = this.listBoxGameTypes.Items.Count > 0;
        }

        private void contextMenuHideGametype_Click(object sender, EventArgs e)
        {
            if (!this.listBoxGameTypes.SelectedIndex.Equals(-1))
                this.listBoxGameTypes.Items.RemoveAt(this.listBoxGameTypes.SelectedIndex);
        }

        private void listBoxGameTypes_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button.Equals(MouseButtons.Right))
            {
                Point point = new Point(e.X, e.Y);
                int index = this.listBoxGameTypes.IndexFromPoint(point);
                this.listBoxGameTypes.SelectedIndex = index;
                if (!index.Equals(-1))
                    this.contextMenuHideGametype.Enabled = true;
                else
                    this.contextMenuHideGametype.Enabled = false;
            }
        }

        private void listBoxMaps_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button.Equals(MouseButtons.Right))
            {
                Point point = new Point(e.X, e.Y);
                int index = this.listBoxMaps.IndexFromPoint(point);
                this.listBoxMaps.SelectedIndex = index;
                if (!index.Equals(-1))
                    this.contextMenuHideMap.Enabled = true;
                else
                    this.contextMenuHideMap.Enabled = false;
            }
        }

        private void contextMenuHideMap_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = this.listBoxMaps.SelectedIndex.Equals(-1);
            contextMenuHideMap.Enabled = this.listBoxMaps.Items.Count > 0;
        }

        private void contextMenuHideMap_Click(object sender, EventArgs e)
        {
            if (!this.listBoxMaps.SelectedIndex.Equals(-1))
                this.listBoxMaps.Items.RemoveAt(this.listBoxMaps.SelectedIndex);
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void clearTextToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}
